/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mycompany.psc.controllers;

import com.mycompany.psc.helpers.DBUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.annotation.Resource;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

/**
 *
 * @author A7med
 */
@Named
@SessionScoped
public class RestoreController implements Serializable {

    private UploadedFile file;
    private String masterPassword;
    private String newPassword;
    private boolean authtincatedRestore;
    private int attempts = 3;

    @Resource(lookup = "PROJECTS_FOLDER")
    private Properties p;
    @Inject
    DBUtils dbUtils;
    private final static String FILE_NAME = "masterPassword.ini";

    public String getMasterPassword() {
        return masterPassword;
    }

    public void setMasterPassword(String masterPassword) {
        this.masterPassword = masterPassword;
    }

    public int getAttempts() {
        return attempts;
    }

    public void setAttempts(int attempts) {
        this.attempts = attempts;
    }

    public String getNewPassword() {
        return newPassword;
    }

    public void setNewPassword(String newPassword) {
        this.newPassword = newPassword;
    }

    public boolean isAuthtincatedRestore() {
        return authtincatedRestore;
    }

    public void setAuthtincatedRestore(boolean authtincatedRestore) {
        this.authtincatedRestore = authtincatedRestore;
    }

    public void setUploadedFile(FileUploadEvent event) {

        file = event.getFile();
        System.out.println("file=" + file.getFileName());
    }

    public void checkRestore() throws IOException {
        FacesContext fc = FacesContext.getCurrentInstance();
        Path path = new File(fc.getExternalContext().getRealPath("/WEB-INF/" + FILE_NAME)).toPath();
        List<String> data = Files.readAllLines(path);
        if (masterPassword.equals(data.get(0))) {
            authtincatedRestore = true;
            fc.addMessage("", new FacesMessage(FacesMessage.SEVERITY_INFO, "Correct password", "you can proceed with restore operation now"));
        } else {
            authtincatedRestore = false;
            fc.addMessage("", new FacesMessage(FacesMessage.SEVERITY_ERROR, "wrong password", "try again"));

        }

    }

    public void restore() {

        FacesContext fc = FacesContext.getCurrentInstance();
        String base = p.getProperty("uri");
        try {
            unZipIt(file.getInputstream(), base);
            dbUtils.restoreDB(base + "/psc.sql");
            fc.addMessage("", new FacesMessage(FacesMessage.SEVERITY_INFO, "Restore Done", "The restore operation is done successfully."));
        } catch (IOException ex) {
            Logger.getLogger(RestoreController.class.getName()).log(Level.SEVERE, null, ex);
            fc.addMessage("", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Restore Failed", "The restore operation has failed. Reason:" + ex.getLocalizedMessage()));
        }

    }

    public void changePassword() throws IOException {
        System.out.println("changing");
        FacesContext fc = FacesContext.getCurrentInstance();
        Path path = new File(fc.getExternalContext().getRealPath("/WEB-INF/" + FILE_NAME)).toPath();
        Files.write(path, newPassword.getBytes());
    }

    private void unZipIt(InputStream zipFile, String outputFolder) {

        byte[] buffer = new byte[1024];

        try {

            //create output directory is not exists
            File folder = new File(outputFolder);
            if (!folder.exists()) {
                folder.mkdir();
            }

            //get the zip file content
            ZipInputStream zis
                    = new ZipInputStream(zipFile);
            //get the zipped file list entry
            ZipEntry ze = zis.getNextEntry();

            while (ze != null) {

                String fileName = ze.getName();
                File newFile = new File(outputFolder + File.separator + fileName);

                System.out.println("file unzip : " + newFile.getAbsoluteFile());

                //create all non exists folders
                //else you will hit FileNotFoundException for compressed folder
                new File(newFile.getParent()).mkdirs();

                FileOutputStream fos = new FileOutputStream(newFile);

                int len;
                while ((len = zis.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                }

                fos.close();
                ze = zis.getNextEntry();
            }

            zis.closeEntry();
            zis.close();

            System.out.println("Done");

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}
